#include <iostream>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include "Socket.hpp"
#include "Protocol.hpp"

using namespace std;

// ./myClient ip port
int main(int argc, char* argv[])
{
    if(argc != 3) {
        cerr << "Usage error" << endl;
        return -1;
    }

    string serverIp = argv[1];
    uint16_t serverPort = stoi(argv[2]);
    Sock sock;
    sock.Socket();

    bool ret = sock.Connect(serverIp, serverPort);
    if(ret == false) {
        return -1;
    }

    srand(time(0));
    const string ops = "+-*/%!@";       // 有一些不正确的符号，目的是为了测试出错的情况
    string inStr = "";

    for (int i = 1; i <= 5; ++i) {
        printf("==============第%d次================\n", i);
        int x = rand() % 100;
        usleep(100);
        int y = rand() % 100;
        usleep(100);
        char op = ops[rand() % ops.size()];
        string text;
        Request req(x, y, op);
        req.printInfo();
        req.serialize(&text);
        text = encode(text);
        printf("将要发送给服务器的请求:\n%s", text.c_str());

        // 向服务器发送数据
        ssize_t n = write(sock.GetFd(), text.c_str(), text.size());
        // n = write(sock.GetFd(), text.c_str(), text.size());
        // n = write(sock.GetFd(), text.c_str(), text.size());
        // n = write(sock.GetFd(), text.c_str(), text.size());
        if(n < 0) {
            cerr << "Client write error!\n" << endl;
            break;
        }

        // 从服务器读取数据
        char buf[128];
        memset(buf, 0, sizeof buf);

        n = read(sock.GetFd(), buf, sizeof(buf));
        if(n > 0) {
            buf[n] = 0;
            inStr += buf;
            string text;

            bool r = decode(inStr, &text);
            if(r == false) {
                cerr << "Client decode error!\n" << endl;
                break;
            }

            Response resp;
            resp.deserialize(text);
            printf("从服务器得到结果:\n");
            resp.printInfo();
        }
        printf("======================================\n");
        sleep(1);
    }
    sock.Close();
    return 0;
}